<template>
  <div
    v-loading="loading"
    class="home-container"
    ref="container"
    @wheel="handleWheel"
  >
    <ul
      class="carousel-container"
      :style="{ marginTop }"
      @transitionend="handleTransitionEnd"
    >
      <li v-for="(item, i) in data" :key="item.id">
        <CarouselItem
          :carousel="item"
          :isShowWords="index === i"
          ref="carouselItem"
        />
      </li>
    </ul>
    <div
      v-show="index >= 1 && data.length"
      @click="switchTo(--index)"
      class="icon icon-up"
    >
      <Icon type="arrowUp" />
    </div>
    <div
      v-show="index < data.length - 1"
      @click="switchTo(++index)"
      class="icon icon-down"
    >
      <Icon type="arrowDown" />
    </div>
    <ul class="indicator">
      <li
        :class="{ active: i === index }"
        v-for="(item, i) in data"
        :key="item.id"
        @click="switchTo(i)"
      ></li>
    </ul>
  </div>
</template>

<style lang="less" scoped>
@import "~@/styles/mixin.less";
@import "~@/styles/var.less";

.home-container {
  width: 100%;
  height: 100%;
  position: relative;
  overflow: hidden; // 创建bfc, 不然控件会被挤到上面

  // // 测试
  // width: 60%;
  // height: 40%;
  // overflow: visible;
  // border: 2px solid #008c8c;
  // margin: 100px auto;

  ul {
    margin: 0;
    padding: 0;
    list-style: none;
    li {
      overflow: hidden;
    }
  }
}
.carousel-container {
  width: 100%;
  height: 100%;
  transition: 0.5s;
  li {
    width: 100%;
    height: 100%;
  }
}
.icon {
  position: absolute;
  z-index: 999;
  left: 50%;
  transform: translateX(-50%);
  font-size: 30px;
  color: @gray;
  cursor: pointer;
  @gap: 20px;
  &.icon-up {
    top: @gap;
    animation: jump-up 2s infinite;
  }
  &.icon-down {
    bottom: @gap;
    animation: jump-down 2s infinite;
  }
  @jump: 5px;
  @keyframes jump-up {
    0% {
      transform: translate(-50%, @jump);
    }
    50% {
      transform: translate(-50%, -@jump);
    }
    100% {
      transform: translate(-50%, @jump);
    }
  }
  @keyframes jump-down {
    0% {
      transform: translate(-50%, -@jump);
    }
    50% {
      transform: translate(-50%, @jump);
    }
    100% {
      transform: translate(-50%, -@jump);
    }
  }
}
.indicator {
  position: absolute;
  z-index: 999;
  right: 20px;
  top: 50%;
  transform: translateY(-50%);
  li {
    width: 7px;
    height: 7px;
    background: @words;
    margin-bottom: 10px;
    border: 1px solid #fff;
    border-radius: 50%;
    box-sizing: border-box;
    cursor: pointer;
    &.active {
      background: #fff;
    }
  }
}
</style>

<script>
import { mapState } from "vuex";
import CarouselItem from "./Carouselitem";
import Icon from "@/components/Icon";

export default {
  // mixins: [fetchData([])],
  components: {
    CarouselItem,
    Icon,
  },
  data() {
    return {
      // 上面使用了mixins混入配置后就不需要下面两行代码了, 包括created中的代码也不需要了
      // banners: [],
      // isLoading: true, // 是否在加载背景图片
      index: 0, // 当前显示的轮播图的索引
      containerHeight: 0, // 默认为0, 待加载出li后重新获取其高度
      switching: false, // 是否正在切页中
    };
  },
  // async created() {
  //   this.banners = await getBanners();
  //   this.isLoading = false;
  // },
  created() {
    this.$store.dispatch("banner/fetchBanner"); // 调用仓库里的方法
  },
  mounted() {
    this.containerHeight = this.$refs.container.clientHeight; // 生成dom元素后再获取高度
    window.addEventListener("resize", this.handleResize); // 注册视口尺寸变化的事件
  },
  destroyed() {
    window.removeEventListener("resize", this.handleResize); // 移除事件[元素被销毁时触发]
  },
  computed: {
    marginTop() {
      return -this.index * this.containerHeight + "px";
    },
    ...mapState("banner", ["loading", "data"]), // 获取仓库里banner的loading和data
  },
  methods: {
    // 切换页面
    switchTo(i) {
      this.index = i;
    },
    // 鼠标滚动时触发
    handleWheel(e) {
      if (this.switching) {
        return;
      }
      if (e.deltaY < 0 && this.index > 0) {
        // console.log("上一个");
        this.switching = true;
        this.index--;
      } else if (e.deltaY > 0 && this.index < this.data.length - 1) {
        // console.log("下一个");
        this.switching = true;
        this.index++;
      }
    },
    // 过渡动画完成时触发
    handleTransitionEnd(e) {
      if (e.target.nodeName !== "UL") {
        return;
      }
      this.switching = false;
      this.showWords(this.index); // 显示当前页的文字
      this.hiddenWords(this.index); // 隐藏其他页文字
    },
    // 视口变化后再次获取高度
    handleResize() {
      // console.log("视口变化");
      this.containerHeight = this.$refs.container.clientHeight;
    },
    // 显示索引页的文字
    showWords(index) {
      const compItem = this.$refs.carouselItem[index].$el;
      // 标题
      const title = compItem.querySelector(".title");
      const titleW = title.clientWidth;
      title.style.opacity = 1;
      title.style.width = 0;
      title.clientWidth; // 强制让浏览器渲染一次[reflow], 不这样做的话浏览器就会直接渲染下面设置的宽度, 就没有过渡动画效果了
      title.style.transition = "1s";
      title.style.width = titleW + "px";

      // 描述
      const desc = compItem.querySelector(".desc");
      const descW = desc.clientWidth;
      desc.style.opacity = 1;
      desc.style.width = 0;
      desc.clientWidth; // 强制让浏览器渲染一次[reflow], 不这样做的话浏览器就会直接渲染下面设置的宽度, 就没有过渡动画效果了
      desc.style.transition = "2s 1.2s";
      desc.style.width = descW + "px";
    },
    // 隐藏其他页文字
    hiddenWords(index) {
      for (let i = 0; i < this.data.length; i++) {
        if (i === index) {
          continue;
        }
        const compItem = this.$refs.carouselItem[i].$el;
        const title = compItem.querySelector(".title");
        if (title.style.opacity === 1) {
          continue;
        }
        title.style.transition = "";
        title.style.opacity = 0;
        const desc = compItem.querySelector(".desc");
        desc.style.transition = "";
        desc.style.opacity = 0;
      }
    },
  },
};
</script>